from typing import Any


class FunctionCandidate:
    """表示待检测函数的一个匹配候选结果的实体类。

       该类封装了候选函数的匹配结果信息、匹配方法及多种相似度指标，
       用于在TPL识别和TPL Version识别场景中传递结果。

       Attributes:
           candidate_id_name (str): 候选 ID 的名称标识（如 "npm_id"）。
           candidate_id (str): 候选的唯一 ID 字符串。
           candidate_name (str): 候选函数的可读名称。
           match_method (str): 使用的匹配方法名称。
           vector_similarity (float): 向量相似度得分，范围 [0, 1]。
           isomorphic_ratio (float): 同构比例，表示AST结构相似程度。
           diff_similarity (float): 异构语义相似度，基于代码差异计算。
           distance (float): 距离度量（欧氏距离），值越小越相似。
           candidate_doc:该函数的具体文档字典
           processing_time:处理时间
       """
    def __init__(
        self,
        candidate_id_name: str = "",
        candidate_id: str = "",
        candidate_name: str = "",
        match_method: str = "",
        vector_similarity: float = float('nan'),
        isomorphic_ratio: float = float('nan'),
        diff_similarity: float = float('nan'),
        distance: float = float('nan'),
        candidate_doc: dict[str, Any] | None = None,  # 改为 None
        processing_time: float = float('nan'),
    ) -> None:
        # 字符串字段

        self.candidate_id_name: str = candidate_id_name
        self.candidate_id: str = candidate_id
        self.candidate_name: str = candidate_name
        self.match_method: str = match_method

        # 浮点数字段
        self.vector_similarity: float = vector_similarity
        self.isomorphic_ratio: float = isomorphic_ratio
        self.diff_similarity: float = diff_similarity
        self.distance: float = distance
        # 安全地初始化可变默认值
        self.candidate_doc = candidate_doc if candidate_doc is not None else {}
        self.processing_time: float = processing_time

    def __str__(self) -> str:
        """返回面向用户的可读字符串表示，类似 Java 的 toString()"""
        return (f"ResultCandidate("
                f"candidate_id_name='{self.candidate_id_name}', "
                f"candidate_id='{self.candidate_id}', "
                f"candidate_name='{self.candidate_name}', "
                f"match_method='{self.match_method}', "
                f"vector_similarity={self.vector_similarity:.4f}, "
                f"isomorphic_ratio={self.isomorphic_ratio:.4f}, "
                f"diff_similarity={self.diff_similarity:.4f}, "
                f"distance={self.distance:.4f} ")

    def __repr__(self) -> str:
        """返回面向开发者的无歧义表示，理想情况下可 eval 重建对象"""
        return (f"ResultCandidate("
                f"candidate_id_name={self.candidate_id_name!r}, "
                f"candidate_id={self.candidate_id!r}, "
                f"candidate_name={self.candidate_name!r}, "
                f"match_method={self.match_method!r}, "
                f"vector_similarity={self.vector_similarity!r}, "
                f"isomorphic_ratio={self.isomorphic_ratio!r}, "
                f"diff_similarity={self.diff_similarity!r}, "
                f"distance={self.distance!r}, ")

    def __eq__(self, other: Any) -> bool:
        """定义对象相等逻辑（可选，但推荐用于测试或集合操作）"""
        if not isinstance(other, FunctionCandidate):
            return False
        return (
            self.candidate_id_name == other.candidate_id_name and
            self.candidate_id == other.candidate_id and
            self.candidate_name == other.candidate_name and
            self.match_method == other.match_method and
            self.vector_similarity == other.vector_similarity and
            self.isomorphic_ratio == other.isomorphic_ratio and
            self.diff_similarity == other.diff_similarity and
            self.distance == other.distance
        )


    @classmethod
    def from_candidate_with_results(
            cls,
            original_candidate: 'FunctionCandidate',
            candidate_name: str,
            isomorphic_ratio: float,
            diff_similarity: float,
            distance: float,
            match_method: str
    ) -> 'FunctionCandidate':
        """
        一个类方法，用于从一个现有的候选对象和计算结果中创建一个新的实例。
        这个方法确保了原始对象不会被修改，同时方便地创建包含结果的新对象。
        """
        # 创建并返回一个新的实例
        return cls(
            candidate_id_name=original_candidate.candidate_id_name,
            candidate_id=original_candidate.candidate_id,
            candidate_name=candidate_name,
            vector_similarity=original_candidate.vector_similarity,
            processing_time=original_candidate.processing_time,
            isomorphic_ratio=isomorphic_ratio,
            diff_similarity=diff_similarity,
            distance=distance,
            match_method=match_method
        )